﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Cms.Data.ORM;
using Cms.Domain;
using Cms.Domain.RepositoryInterfaces;
using Cms.Tests.Unit.Application;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Cms.Tests.Unit.Domain
{
    [TestClass]
    public class PermissionCheckerTests
    {
        private Administrator _adminUser;
        private Administrator _adminWithNoPermissions;
        private Administrator _adminWithSomePermissions;
        private AdministratorGroup _somePermissionsGroup;
        private IPermissionRepository _permissionRepository;

        private void Prepare()
        {
            _adminUser = new Administrator();
            AdministratorGroup administratorGroup = new AdministratorGroup() { ID = 1 };
            _adminUser.Group = administratorGroup;
            _adminWithNoPermissions = new Administrator();
            AdministratorGroup noPermissionsGroup = new AdministratorGroup();
            _adminWithNoPermissions.Group = noPermissionsGroup;
            _adminWithSomePermissions = new Administrator();
            _somePermissionsGroup = new AdministratorGroup();
            _adminWithSomePermissions.Group = _somePermissionsGroup;
            _permissionRepository = new PermissionRepositoryMock();
            Installer installer = new Installer(_permissionRepository);
            installer.CreatePermissions();
        }

        [TestMethod]
        public void ConfigureFirstSite_Admin_Allowed()
        {
            Prepare();
            Assert.IsTrue(_adminUser.HasPermission.ConfigureFirstSite);
        }

        [TestMethod]
        public void ConfigureFirstSite_NoPermission_Denied()
        {
            Prepare();
            Assert.IsFalse(_adminWithNoPermissions.HasPermission.ConfigureFirstSite);
        }

        [TestMethod]
        public void ConfigureFirstSite_ExplicitPermission_Allowed()
        {
            Prepare();
            _somePermissionsGroup.Permissions.Add(_permissionRepository.GetPermission(1));
            Assert.IsTrue(_adminWithSomePermissions.HasPermission.ConfigureFirstSite);
        }

        [TestMethod]
        public void Users_ExplicitPermission_Allowed()
        {
            Prepare();
            _somePermissionsGroup.Permissions.Add(_permissionRepository.GetPermission(49));
            Assert.IsTrue(_adminWithSomePermissions.HasPermission.Users);
        }

        [TestMethod]
        public void EditUser_ExplicitPermission_Allowed()
        {
            Prepare();
            _somePermissionsGroup.Permissions.Add(_permissionRepository.GetPermission(50)); 
            Assert.IsTrue(_adminWithSomePermissions.HasPermission.EditUser);
        }

        [TestMethod]
        public void AddUser_ExplicitPermission_Allowed()
        {
            Prepare();
            _somePermissionsGroup.Permissions.Add(_permissionRepository.GetPermission(51));
            Assert.IsTrue(_adminWithSomePermissions.HasPermission.AddUser);
        }

        #region PermissionRepositoryMock Class

        private class PermissionRepositoryMock : IPermissionRepository
        {
            private readonly IList<Permission> _permissions;

            public PermissionRepositoryMock()
            {
                _permissions = new List<Permission>();
            }
            public void SavePermission(Permission permission)
            {
                _permissions.Add(permission);
            }

            public IList<Permission> GetPermissions()
            {
                return _permissions;
            }

            public Permission GetPermission(int id)
            {
                return _permissions.FirstOrDefault(p => p.ID == id);
            }
        }

        #endregion
    }
}
